package com.example.roam.view;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.RectF;
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.ScaleGestureDetector;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewTreeObserver;
public class MyMapView extends androidx.appcompat.widget.AppCompatImageView implements  ScaleGestureDetector.OnScaleGestureListener ,View.OnClickListener {
    private Matrix matrix;
    private int drawableWidth , drawableHeight , viewWidth , viewHeight;
    private static final String TAG = "MyMapView";
    private ScaleGestureDetector scaleGestureDetector;
    private int mTouchSlop; //是否可以拖拽

    private MyGlobal myGlobal = new MyGlobal();
    public MyMapView(Context context) {
        super(context);
        init();
    }

    public MyMapView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    public MyMapView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init();
    }

    public void init(){
        matrix = new Matrix();
        scaleGestureDetector = new ScaleGestureDetector(this.getContext(),this);
    }

    @Override
    public boolean onScale(ScaleGestureDetector detector) {
        float scaleFactor = detector.getScaleFactor();
        matrix.postScale(scaleFactor,scaleFactor,detector.getFocusX(),detector.getFocusY());
        setImageMatrix(matrix);
        onChangedListner.onChanged(getMatrixRect());
        return true;
    }

    @Override
    public boolean onScaleBegin(ScaleGestureDetector detector) {
        return true;
    }

    @Override
    public void onScaleEnd(ScaleGestureDetector detector) {
        Log.i(TAG, "onScaleEnd: 手势结束！");
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        scaleGestureDetector.onTouchEvent(event);
        moveByTouchEvent(event);
        return true;
    }

    @Override
    public void onClick(View v) {
    }

    public class MyGlobal implements ViewTreeObserver.OnGlobalLayoutListener{

        @Override
        public void onGlobalLayout() {  // 监听缩放
            Drawable drawable = getDrawable();
            drawableWidth = drawable.getIntrinsicWidth();
            drawableHeight = drawable.getIntrinsicHeight(); // 图片
            viewHeight = getHeight();
            viewWidth = getWidth(); // 组件
            float SCALE_ADAPTIVE = 1.0f;
            if (drawableWidth >= viewWidth && drawableHeight <= viewHeight) {//如果图片固宽大于View宽,固高小于View高，
                SCALE_ADAPTIVE = viewHeight * 1f / drawableHeight;   // 那么只需针对高度等比例放大图片（这里有别于查看大图的处理方式）
            } else if (drawableWidth <= viewWidth && drawableHeight >= viewHeight) {//固宽小于View宽,固高大于View高，针对宽度放大
                SCALE_ADAPTIVE = viewWidth * 1f / drawableWidth;
            } else if (drawableWidth >= viewWidth && drawableHeight >= viewHeight || drawableWidth <= viewWidth && drawableHeight <= viewHeight) {//固宽和固高都大于或都小于View的宽高，
                SCALE_ADAPTIVE = Math.max(viewWidth * 1f / drawableWidth, viewHeight * 1f / drawableHeight);//只取对宽和对高之间最小的缩放比例值（这里有别于查看大图的处理方式）
            }
            matrix.setTranslate((viewWidth-drawableWidth) * 1.0f / 2 , (viewHeight - drawableHeight ) * 1.0f / 2);
            matrix.postScale(SCALE_ADAPTIVE, SCALE_ADAPTIVE, viewWidth * 1f / 2, viewHeight * 1f / 2 );
            setImageMatrix(matrix);
            getViewTreeObserver().removeOnGlobalLayoutListener(this::onGlobalLayout);
            onChangedListner.onChanged(getMatrixRect());
        }
    }

    int mLastX;      //上一次触点中心坐标
    int mLastY;
    int mLastPointCount;     //上一次拖动图片的触点数（手指数）

    // 1. 居中
    private void moveByTouchEvent(MotionEvent event) {     // 移动代码 1.
        switch (event.getAction()) {
            case MotionEvent.ACTION_MOVE://手势移动
                RectF rect = getMatrixRect();
                if (rect.width() <= getWidth() && rect.height() <= getHeight()) {  //rect.width()图片的宽度，getWidth() View的宽度
                    //图片宽高小于等于View宽高，即图片可以完全显示于屏幕中，那就没必要拖动了
                    return;
                }

                Log.i(TAG, "moveByTouchEvent: rect.width():"+rect.width()+" getWidth():"+getWidth());

                //计算多个触点的中心坐标
                int x = 0;
                int y = 0;
                int pointerCount = event.getPointerCount();//获取触点数（手指数）
                for (int i = 0; i < pointerCount; i++) {
                    x += event.getX(i);
                    y += event.getY(i);
                }
                //得到最终的中心坐标
                x /= pointerCount;
                y /= pointerCount;

                //如果触点数（手指数）发生变化，需要重置上一次中心坐标和数量的参考值
                if (mLastPointCount != pointerCount) {
                    mLastX = x;
                    mLastY = y;
                    mLastPointCount = pointerCount;
                }
                int deltaX = x - mLastX;//X方向的位移
                int deltaY = y - mLastY;//Y方向的位移
//                到达边界代码
                if (isCanDrag(deltaX, deltaY)) {
//                    图片宽小于等于view宽，则X方向不需要移动
                    if (rect.width() <= getWidth()) {
                        deltaX = 0;
                    }
                    //图片高小于等于view高，则Y方向不需要移动
                    if (rect.height() <= getHeight()) {
                        deltaY = 0;
                    }
                }

                //完成缩放
                matrix.postTranslate(deltaX, deltaY);
                setImageMatrix(matrix);
                onChangedListner.onChanged(getMatrixRect());
                //交换中心坐标值，作为下次移动事件的参考值
                mLastX = x;
                mLastY = y;
                break;
            case MotionEvent.ACTION_CANCEL://取消

            case MotionEvent.ACTION_UP://释放
                mLastPointCount = 0;//触点数置零，便于下次判断是否重置mLastX和mLastY
                break;
        }
    }

    //是否可以拖拽图片 2.
    private boolean isCanDrag(int deltaX, int deltaY) {
        return Math.sqrt(deltaX * deltaX + deltaY * deltaY) >= mTouchSlop * 0.8 ;
    }

    private RectF getMatrixRect() {  //3. 获取图片的
        RectF rect = new RectF();
        Drawable drawable = getDrawable();
        if (drawable != null) {
            rect.set(0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight());
        }
        matrix.mapRect(rect);
        Log.i(TAG, "getMatrixRect: ");  // 测量的宽度和高度会随着手势放大而大
        return rect;
    }


    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
    }

    private OnMapStateChangedListner onChangedListner;//地图状态变化监听对象

    public void setOnMapStateChangedListner(OnMapStateChangedListner l) {
        onChangedListner = l;
    }

    /**
     * 监听地图自适应屏幕缩放、手势移动以及缩放的状态变化接口
     */
    public interface OnMapStateChangedListner {
        void onChanged(RectF rectF);
    }

    @Override
    protected void onAttachedToWindow() {
        super.onAttachedToWindow();
        //订阅布局监听
        getViewTreeObserver().addOnGlobalLayoutListener(myGlobal);
    }

    @Override
    protected void onDetachedFromWindow() {
        super.onDetachedFromWindow();
        //取消订阅
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
            getViewTreeObserver().removeOnGlobalLayoutListener(myGlobal);
        }
    }
}
